package com.googlecode.linkmein.service

import com.google.gdata.client.contacts.ContactsService
import com.google.gdata.data.PlainTextConstruct
import com.google.gdata.data.contacts.*
import com.google.gdata.data.extensions.Email
import com.google.gdata.data.extensions.PhoneNumber
import com.googlecode.linkmein.domain.Employee
import com.googlecode.linkmein.domain.Employees

class GmailContactsService {

  String groupName = "ThoughtWorksChina"
  String contactUrl = "http://www.google.com/m8/feeds/contacts/default/full"
  String groupUrl = "http://www.google.com/m8/feeds/groups/default/full"
  ContactFeed contactFeed
  ContactGroupFeed contactGroupFeed
  ContactsService contactsService

  public GmailContactsService() {
  }

  public void setUpService(String token) {
    try {
      contactsService = new ContactsService("link.me.in")
      contactsService.setAuthSubToken(token)
      contactFeed = contactsService.getFeed(new URL(contactUrl), ContactFeed.class)
      contactGroupFeed = contactsService.getFeed(new URL(groupUrl), ContactGroupFeed.class)
    } catch (Exception e) {
    }
  }

  public String getGmail() {
    return contactFeed ? contactFeed.getId() : ""
  }

  public void createContactsForCurrentUser(FetchEmployeeService fetchEmployeeService) {
    try {
      ContactGroupEntry group = fetchGroup()
      createContactsByGroup(group, fetchEmployeeService)
    } catch (Exception e) {
      e.printStackTrace()
    }
  }

  private ContactGroupEntry fetchGroup() {
    ContactGroupEntry group = getGroupByName()
    if (!group) {
      group = createGroup()
    }
    return group
  }

  private ContactGroupEntry createGroup() {
    ContactGroupEntry group = new ContactGroupEntry()
    group.setTitle(new PlainTextConstruct(groupName))
    return contactsService.insert(new URL(groupUrl), group)
  }

  private void createContactsByGroup(ContactGroupEntry group, FetchEmployeeService fetchEmployeeService) {
    Employees employees = fetchEmployeeService.getEmployees()
    employees.each {Employee employee ->
      updateContactByEmployee(employee, group)
    }
  }

  private void updateContactByEmployee(Employee employee, ContactGroupEntry group) {

    if (getContactByEmployee(employee)) {
      return
    }

    ContactEntry contact = new ContactEntry()
    GroupMembershipInfo groupMembershipInfo = new GroupMembershipInfo()
    groupMembershipInfo.setHref(group.getId())
    contact.addGroupMembershipInfo(groupMembershipInfo)

    contact.setTitle(new PlainTextConstruct(employee.englishName))
    contact.setContent(new PlainTextConstruct(employee.englishName + " " + employee.chineseName))

    String email = employee.getGmail()
    if (!email.isEmpty()) {
      Email primaryMail = new Email()
      primaryMail.setAddress(email)
      primaryMail.setRel(Email.Rel.WORK)
      primaryMail.setPrimary(true)
      contact.addEmailAddress(primaryMail)
    }

    String phone = employee.getCellphone()
    if (!phone.isEmpty()) {
      PhoneNumber phoneNumber = new PhoneNumber()
      phoneNumber.setPhoneNumber(phone)
      phoneNumber.setPrimary(true)
      phoneNumber.setRel(PhoneNumber.Rel.MOBILE)
      contact.addPhoneNumber(phoneNumber) 
    }
    
    contactsService.insert(new URL(contactUrl), contact)
  }

  private ContactGroupEntry getGroupByName() {
    for (ContactGroupEntry entry: contactGroupFeed.entries) {
      if (entry.getTitle().getPlainText().equals(groupName)) {
        return entry;
      }
    }
    return null;
  }

  private ContactEntry getContactByEmployee(Employee employee) {
    for (ContactEntry entry: contactFeed.entries) {
      for (Email email: entry.getEmailAddresses()) {
        if (email.getAddress().equals(employee.getGmail())) {
          return entry
        }
      }
    }
    return null
  }
}